﻿using Magellan.Routing;

namespace Magellan.Framework
{
    internal interface INavigationEvent
    {
        NavigationRequest Request { get; set; }
    }

    public abstract class NavigationEvent : INavigationEvent
    {
        private NavigationRequest _request;

        protected NavigationEvent()
        {
        }

        public NavigationRequest Request
        {
            get { return _request; }
        }

        NavigationRequest INavigationEvent.Request
        {
            get
            {
                return Request;
            }
            set
            {
                _request = value;
            }
        }
    }

    // TODO: Routing should introduce other events

    /// <summary>
    /// The first event. This occurs at the start of the navigation request before the controller has 
    /// been resolved.
    /// </summary>
    public class BeginRequestNavigationEvent : NavigationEvent
    {
    }

    /// <summary>
    /// This event indicates that the controller is about to be resolved by name from the 
    /// current controller factory.
    /// </summary>
    public class ResolvingControllerNavigationEvent : NavigationEvent
    {
    }

    /// <summary>
    /// This event indicates that the controller has been resolved, and the action is now 
    /// about to be resolved.
    /// </summary>
    public class ResolvingActionNavigationEvent : NavigationEvent
    {
    }

    /// <summary>
    /// This event indicates that the action has been resolved, and pre-action filters are 
    /// about to be invoked.
    /// </summary>
    public class PreActionFiltersNavigationEvent : NavigationEvent
    {
    }

    /// <summary>
    /// This event indicates that pre-action filters have been invoked, and the action 
    /// is about to to executed. This event does not always occur (pre-action filters can cancel the 
    /// navigation request, for example).
    /// </summary>
    public class ExecutingActionNavigationEvent : NavigationEvent
    {
    }

    /// <summary>
    /// This event indicates that the action has been invoked, and post-action filters are 
    /// about to to executed. This event does not always occur (pre-action filters can cancel the 
    /// navigation request, for example).
    /// </summary>
    public class PostActionFiltersNavigationEvent : NavigationEvent
    {
    }

    /// <summary>
    /// This event indicates that the action has been executed and all 
    /// <see cref="IActionFilter">action filters</see> have been invoked. The result is now about to be 
    /// evaluated. This event does not always occur (action filters can cancel the navigation request, 
    /// for example).
    /// </summary>
    public class PreResultFiltersNavigationEvent : NavigationEvent
    {
    }

    /// <summary>
    /// This event indicates that the pre-result filters have been executed, and the result
    /// is about to be executed (this is typically when views are rendered). This event does not always 
    /// occur (action filters or pre-action filters can cancel the navigation request, for example). 
    /// </summary>
    public class ExecutingResultNavigationEvent : NavigationEvent
    {
    }

    /// <summary>
    /// This event indicates that the result has been executed (and views have been rendered)
    /// and the post-result filters are about to be executed.
    /// </summary>
    public class PostResultFiltersNavigationEvent : NavigationEvent
    {
    }
    
    /// <summary>
    /// The final navigation event. This indicates that the navigation request has been completed 
    /// (whether successfully or failed), any views have been rendered and any resources from the 
    /// navigation request have been cleared up.
    /// </summary>
    public class CompleteNavigationEvent : NavigationEvent
    {
    }
}